如果直接将事件处理函数(其中需要修改state)进行debounce装饰就会报如下错误,

The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.
SyntheticEvent 对象是通过合并得到的。 这意味着在事件回调被调用后,SyntheticEvent 对象将被重用并且所有属性都将被取消。这是出于性能原因。因此,您无法以异步方式访问该事件。

因为react中的event是池化的合成事件,debounce处理后就是异步操作,所以再次获取event 是空对象。因此将过程拆解,handleEvent 照常处理event 对象再将修改state的操作进行防抖即可。

import React from "react";
import ReactDOM from "react-dom";
import { debounce, get } from "lodash";

import "./styles.css";

export class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.genDebounceFn = this.genDebounceFn.bind(this);
  }

  handleEvent(e) {
    const newState = {
      ...this.state
    };
    // 这里引用了SyntheticEvent event 对象的type 方法
    newState[e.type] = get(this.state, e.type, 0) + 1;
    this.modifyState.call(this, newState);
  }

  componentWillReceiveProps(nextProps) {
    this.genDebounceFn(nextProps);
  }

  componentDidMount() {
    this.genDebounceFn(this.props);
  }

  genDebounceFn(props) {
    this.modifyState = debounce(newState => {
      this.setState(() => newState);
    }, props.delay);
  }

  render() {
    const eventCount = Object.keys(this.state).map(e => {
      return (
        <div key={e}>
          {e}:{this.state[e]}
        </div>
      );
    });
    return (
      <>
        delay: {this.props.delay}
        <br />
        <span>{eventCount}</span>
        <button
          onClick={this.handleEvent.bind(this)}
          onMouseOver={this.handleEvent.bind(this)}
        >
          click me OR mouseOver me
        </button>
      </>
    );
  }
}

点击预览


大熊维尼
52 声望1 粉丝

« 上一篇
Rxjs 学习